/**************************************************************************************************
	$Header: /pub/cvsroot/mydns/src/mydns/queue.c,v 1.17 2003/07/27 08:32:23 bboy Exp $

	Copyright (C) 2002, 2003  Don Moore <bboy@bboy.net>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at Your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
**************************************************************************************************/

#include "named.h"


/**************************************************************************************************
	QUEUE_INIT
	Creates a new queue and returns a pointer to it.
**************************************************************************************************/
QUEUE *
queue_init(void)
{
	QUEUE *q;

	if (!(q = malloc(sizeof(QUEUE))))
		Err("malloc");
	q->size = 0;
	q->head = q->tail = (TASK *)NULL;
	return (q);
}
/*--- queue_init() ------------------------------------------------------------------------------*/


/**************************************************************************************************
	ENQUEUE
	Enqueues a TASK item, appending it to the end of the list.
**************************************************************************************************/
int
enqueue(QUEUE *q, TASK *t)
{
	t->next = NULL;												/* Append to list */
	if (!q->head)
	{
		q->head = t;
		t->prev = NULL;
	}
	if (!q->tail)
	{
		q->tail = t;
		t->prev = NULL;
	}
	else
	{
		q->tail->next = t;
		t->prev = q->tail;
	}
	q->size++;
	task_init_header(t);											/* Initialize header fields */
	if (reply_init(t) < 0)										/* Initialize reply */
		return Warnx("%s: %s", desctask(t), _("failed to initialize reply"));

	t->len = 0;														/* Reset TCP packet len */

	if (t->protocol == SOCK_STREAM)
		Status.tcp_requests++;
	else
		Status.udp_requests++;

	return (0);
}
/*--- enqueue() ---------------------------------------------------------------------------------*/


/**************************************************************************************************
	DEQUEUE
	Removes the item specified from the queue.  Pass this a pointer to the actual element in the
	queue.
	For `error' pass 0 if the task was dequeued due to sucess, 1 if dequeued due to error.
**************************************************************************************************/
void
dequeue(QUEUE *q, TASK *t)
{
	if (err_verbose)											/* Output task info if verbose */
		task_output_info(t);

	if (t->hdr.rcode < MAX_RESULTS)						/* Store results in stats */
		Status.results[t->hdr.rcode]++;

	if (t == q->head)											/* Item is head of list */
	{
		q->head = t->next;
		if (q->head == NULL)
			q->tail = NULL;
		else
			t->next->prev = NULL;
	}
	else															/* Item is not head of list */
	{
		t->prev->next = t->next;
		if (t->next == NULL)
			q->tail = t->prev;
		else
			t->next->prev = t->prev;
	}
	q->size--;
	task_free(t);
}
/*--- dequeue() ---------------------------------------------------------------------------------*/

/* vi:set ts=3: */
